package com.woniu.his.mms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.his.bms.client.BillRecordClient;
import com.woniu.his.bms.client.result.BillRecordResult;
import com.woniu.his.dms.client.CaseHistoryClient;
import com.woniu.his.dms.client.result.CaseHistoryResult;
import com.woniu.his.exception.HisException;
import com.woniu.his.mms.common.MmsResultCode;
import com.woniu.his.mms.common.MmsStatusEnum.MmsStatusCode;
import com.woniu.his.mms.infra.model.HerbalItemRecord;
import com.woniu.his.mms.infra.model.HerbalPrescriptionRecord;
import com.woniu.his.mms.infra.mapper.HerbalPrescriptionRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.his.mms.service.DrugService;
import com.woniu.his.mms.service.HerbalItemRecordService;
import com.woniu.his.mms.service.HerbalPrescriptionRecordService;
import com.woniu.his.mms.service.dto.DrugDto;
import com.woniu.his.mms.service.dto.HerbalItemDto;
import com.woniu.his.mms.service.dto.HerbalPrescriptionDto;
import com.woniu.his.mms.service.param.CreateHerbalPrescriptionParam;
import com.woniu.his.mms.service.param.HerbalItemParam;
import com.woniu.his.result.Result;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 草药处方记录表 服务实现类
 * </p>
 *
 * @author ZJH
 * @since 2022-11-28
 */
@Service
public class HerbalPrescriptionRecordServiceImpl extends ServiceImpl<HerbalPrescriptionRecordMapper, HerbalPrescriptionRecord> implements HerbalPrescriptionRecordService {

    @Resource
    private DrugService drugService;

    @Resource
    private HerbalItemRecordService herbalItemRecordService;

    @Resource
    private CaseHistoryClient caseHistoryClient;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private BillRecordClient billRecordClient;

    @Override
    public Boolean createHerbalPrescription(CreateHerbalPrescriptionParam param) {
        HerbalPrescriptionRecord record = getOne(new QueryWrapper<HerbalPrescriptionRecord>().eq("case_history_id", param.getCaseHistoryId()));
        if(record!=null) throw new HisException(MmsResultCode.PRESCRIPTION_ALREADY_EXISTS);
        if(param.getHerbalItemParams().size()>5) throw new HisException(MmsResultCode.PRESCRIPTION_TOO_MANY_DRUG);
        //创建处方数据
        HerbalPrescriptionRecord herbalPrescriptionRecord = BeanUtil.copyProperties(param, HerbalPrescriptionRecord.class);
        herbalPrescriptionRecord.setCreateTime(DateUtil.formatDateTime(new Date()));
        herbalPrescriptionRecord.setHerbalPrescriptionStatus(MmsStatusCode.HERBAL_PRESCRIPTION_STATUS_NOT_PAY.getCode());
        List<DrugDto> drugDtos = drugService.queryAllDrug();
        BigDecimal allAmount = new BigDecimal(0.00);
        int num = 0;
        for (DrugDto drugDto : drugDtos) {
            for (HerbalItemParam herbalItemParam : param.getHerbalItemParams()) {
                if(drugDto.getId()==herbalItemParam.getDrugId()){
                    if(drugDto.getStatusDrug().equals(MmsStatusCode.DRUG_STATUS_OFF.getCode())){
                        throw new HisException(MmsResultCode.DRUG_STATUS_OFF);
                    }
                    num++;
                    BigDecimal price = drugDto.getPrice();
                    BigDecimal totalNum = BigDecimal.valueOf(herbalItemParam.getTotalNum());
                    allAmount = allAmount.add(price.multiply(totalNum));
                }
            }
        }
        if(num!=param.getHerbalItemParams().size()) throw new HisException(MmsResultCode.DRUG_NOT_EXISTS);
        herbalPrescriptionRecord.setAmount(allAmount);
        //生成账单
        Result<BillRecordResult> result = billRecordClient.createBillRecord("HERBAL",allAmount ,param.getCaseHistoryId());
        herbalPrescriptionRecord.setBillId(result.getData().getId());
        save(herbalPrescriptionRecord);
        //生成条目记录
        List<HerbalItemParam> herbalItemParams = param.getHerbalItemParams();
        List<HerbalItemRecord> herbalItemRecords = BeanUtil.copyToList(herbalItemParams, HerbalItemRecord.class);
        for (HerbalItemRecord herbalItemRecord : herbalItemRecords) {
            herbalItemRecord.setStatusHir(MmsStatusCode.HERBAL_PRESCRIPTION_STATUS_NOT_PAY.getCode());
            herbalItemRecord.setPrescriptionId(herbalPrescriptionRecord.getId());
        }
        herbalItemRecordService.saveBatch(herbalItemRecords);
        //存入redis
        RBucket<Object> bucket = redissonClient.getBucket("HerbalPrescription:" + param.getCaseHistoryId());
        bucket.set(herbalPrescriptionRecord);
        return true;
    }

    @Override
    public Boolean deleteHerbalPrescription(List<Long> ids) {
        List<HerbalPrescriptionRecord> prescriptions = list(new QueryWrapper<HerbalPrescriptionRecord>().in("id", ids));
        for (HerbalPrescriptionRecord prescription : prescriptions) {
            if(prescription.getHerbalPrescriptionStatus().equals(MmsStatusCode.HERBAL_PRESCRIPTION_STATUS_DELETE.getCode())){
                throw new HisException(MmsResultCode.DRUG_DELETED);
            }
            prescription.setHerbalPrescriptionStatus(MmsStatusCode.HERBAL_PRESCRIPTION_STATUS_DELETE.getCode());
        }
        return true;
    }

    @Override
    public List<HerbalPrescriptionDto> queryHerbalPrescriptionByIds(List<Long> ids) {
        List<HerbalPrescriptionRecord> prescriptions = list(new QueryWrapper<HerbalPrescriptionRecord>().in("id", ids));
        List<HerbalItemRecord> items = herbalItemRecordService.list(new QueryWrapper<HerbalItemRecord>().in("prescriptionId", ids));
        List<HerbalPrescriptionDto> herbalPrescriptionDtos = BeanUtil.copyToList(prescriptions, HerbalPrescriptionDto.class);
        for (HerbalPrescriptionDto herbalPrescriptionDto : herbalPrescriptionDtos) {
            herbalPrescriptionDto.setHerbalItemDtos(new ArrayList<>());
            for (HerbalItemRecord item : items) {
                if(item.getPrescriptionId()==herbalPrescriptionDto.getId()){
                    HerbalItemDto herbalItemDto = BeanUtil.copyProperties(item, HerbalItemDto.class);
                    herbalPrescriptionDto.getHerbalItemDtos().add(herbalItemDto);
                }
            }
        }
        return herbalPrescriptionDtos;
    }

    @Override
    public HerbalPrescriptionDto queryHerbalPrescriptionByCaseId(Long caseId) {
        //根据病历id查处方
        HerbalPrescriptionRecord prescription = getOne(new QueryWrapper<HerbalPrescriptionRecord>().eq("case_history_id", caseId));
        if(prescription==null) throw new HisException(MmsResultCode.PRESCRIPTION_NOT_EXISTS);
        HerbalPrescriptionDto herbalPrescriptionDto = BeanUtil.copyProperties(prescription, HerbalPrescriptionDto.class);
        List<HerbalItemRecord> items = herbalItemRecordService.list(new QueryWrapper<HerbalItemRecord>().eq("prescription_id", herbalPrescriptionDto.getId()));
        List<HerbalItemDto> herbalItemDtos = BeanUtil.copyToList(items, HerbalItemDto.class);
        herbalPrescriptionDto.setHerbalItemDtos(herbalItemDtos);
        return herbalPrescriptionDto;
    }

    @Override
    public HerbalPrescriptionDto queryHerbalPrescriptionByBillId(Long billId) {
        HerbalPrescriptionRecord record = getOne(new QueryWrapper<HerbalPrescriptionRecord>().eq("bill_id", billId));
        if(record==null) throw new HisException(MmsResultCode.PRESCRIPTION_NOT_EXISTS);
        List<HerbalItemRecord> itemRecords = herbalItemRecordService.list(new QueryWrapper<HerbalItemRecord>().eq("prescription_idd", record.getId()));
        HerbalPrescriptionDto herbalPrescriptionDto = BeanUtil.copyProperties(record, HerbalPrescriptionDto.class);
        List<HerbalItemDto> herbalItemDtos = BeanUtil.copyToList(itemRecords, HerbalItemDto.class);
        herbalPrescriptionDto.setHerbalItemDtos(herbalItemDtos);
        return herbalPrescriptionDto;
    }

    @Override
    public Boolean paySuccess(Long billId) {
        HerbalPrescriptionRecord herbalPrescriptionRecord = getOne(new QueryWrapper<HerbalPrescriptionRecord>().eq("bill_id", billId));
        herbalPrescriptionRecord.setHerbalPrescriptionStatus(MmsStatusCode.HERBAL_PRESCRIPTION_STATUS_PAID.getCode());
        updateById(herbalPrescriptionRecord);
        return true;
    }
}
